﻿using System;
using CMPart;
using CSUtils;
using UnityEngine;
using DG.Tweening;
using GlobalTripleJump;
using U3dUtils;

namespace TripleJump {
    public class CCameraControl : MonoBehaviour {
        const string _tag = "CCameraControl";

        Transform camera;
        Transform targetTf;

        public static CCameraControl GetObj(Camera cam) {
            if (cam == null) {
                cam = Camera.main;
            }
            var obj = cam.GetComponent<CCameraControl>();
            if (obj == null) {
                obj = cam.gameObject.AddComponent<CCameraControl>();
            }
            obj.Init(cam);
            return obj;
        }

        void Init(Camera cam) {
            camera = cam.transform;
            targetTf = new GameObject("CamControl.target").transform;
            camera.SetParent(targetTf);

            _camDefOffset = GlobalTripleJumpCfg.cameraDefOffect;
            _camDefTargetOffset = GlobalTripleJumpCfg.cameraDefTargetOffect;
            _camFlyOffset = GlobalTripleJumpCfg.cameraFlyOffect;
            _camFlyTargetOffset = GlobalTripleJumpCfg.cameraFlyTargetOffect;
        }

        public Light light;
        Vector3 _camDefOffset, _camDefTargetOffset;
        Vector3 _camFlyOffset, _camFlyTargetOffset;

        public void SetLight(Light light) {
            light.transform.SetParent(targetTf);
            light.transform.localEulerAngles = new Vector3(44, 30, 34);
            light.shadowResolution = UnityEngine.Rendering.LightShadowResolution.High;
            //light.cullingMask =1<<0 |1<<1 |1<<2 |1<<16 |1<<17;

            //GameObject tt= GameObject.Instantiate(light.gameObject, target);
            //tt.name = "firstRoleLight";
            //tt.GetComponent<Light>().cullingMask = 1<<15;
        }

        public void GameReset() {
            isPassStartPos = false;
            flyCount = 0;
            //Debug.LogErrorFormat("d标位置..._____________{0}", target.position);
            CDelayMain.Delay(0.15f).onCallback = delegate {
                var firstRolePos = CGameCore.GetFirstHeroPos();
                targetTf.position = firstRolePos + _camDefTargetOffset;
                //Debug.LogErrorFormat("相机目标位置..._____________{0}", target.position);
                camera.localPosition = _camDefOffset;
                lastDeltaTime = 0.04f;
                isRuning = false;
                isCanChangeLerp = true;
                camera.LookAt(targetTf.position);
                // S_Refresh();
            };
        }

        bool isPassStartPos;

        public void GameStart() {
            isPassStartPos = false;
            // lerpRatio = 1;
            isRuning = true;
            lerp = 0.8f;
            isCanChangeLerp = false;
            camera.DOLocalMove(_camFlyOffset, 1);
            _camJumpLerpValue = GlobalTripleJumpCfg.cameraStartLerpValue01;
            CDelayMain.Delay(2.5f + _camJumpLerpValue[0]).onCallback = delegate {
                //CDelayMain.Delay (2.5f+ o_cameraJumpLerpValue[0]).SetPauseEnd("").onCallback = delegate () {
                isCanChangeLerp = true;
            };
        }

        public void GameEnd() {
        }

        public void SetIsHelpStep(bool isHelpStep) {
            CLog.i(_tag, $"SetIsHelpStep()..设置角色是否能够运行.....isHelpStep={isHelpStep}/isRuning={isRuning}");
            this.isHelpStep = isHelpStep;
        }

        bool isHelpStep;
        //0.73,2.88,-4.6
        //32,-9,0
        bool isRuning;

        void Update() {
            if (isHelpStep) {
                return;
            }
            if (isRuning == false) {
                return;
            }
            _Refresh();
        }

        bool isCanChangeLerp;
        float lastDeltaTime = 0.04f;

        void _Refresh() {
            float deltaTime = Time.deltaTime;
            deltaTime = Mathf.Lerp(lastDeltaTime, deltaTime, 0.2f);
            lastDeltaTime = deltaTime;
            if (isPassStartPos == false && flyCount > 0) {
                isPassStartPos = true;
            }
            var downDirection = CCylinderTerrain.inst.circle.para.centerPoint - targetTf.position;
            //Vector3 downDirection0 = downDirection.normalized;
            if (isCanChangeLerp) {
                if (lerp < lerpMax) {
                    //lerp += 20 * lerpRatio * deltaTime;
                    lerp += lerpSpeed * deltaTime;
                }
            }
            var firstRolePos = CGameCore.GetFirstHeroPos();
            var vv = Quaternion.FromToRotation(Vector3.up, -downDirection) * _camFlyTargetOffset;
            targetTf.position = Vector3.Lerp(targetTf.position, firstRolePos + vv, lerp * deltaTime);

            //Debug.DrawLine(target.position, parameter.circle.parameter.centerPoint, Color.red, 1000);
            //if (o_FlyState != E_FlyState.e07_toGround) {
            //    Debug.LogErrorFormat("Camera____{0}___{1}____{2}___{3}", lerp, deltaTime, .deltaTime, frestRoleRoot.position.y);
            //}
            if (isPassStartPos) {
                targetTf.rotation = CCylinderTerrain.inst.circle.ToCircleRotation(targetTf.position);
            } else {
                targetTf.localEulerAngles = Vector3.zero;
            }

            var upPoint = targetTf.position - downDirection * 100;

            camera.LookAt(targetTf.position, upPoint);

            var offset = Mathf.Lerp(0, -10, (downDirection.magnitude - CCylinderTerrain.CPara.radius) / 200);
            camera.localEulerAngles = camera.localEulerAngles.ResetZ(offset);
        }

        float maxHighPointTime;
        int flyCount;
        /// <summary>
        /// 相机追踪渐变
        /// <para>"1=渐变开始时间,2=差值开始系数,3=差值速度,4=差值结束系数"</para>
        /// </summary>
        float[] _camJumpLerpValue {
            get { return _cameraJumpLerpValue; }
            set {
                _cameraJumpLerpValue = value;
                lerp = _cameraJumpLerpValue[1];
                lerpSpeed = _cameraJumpLerpValue[2];
                lerpMax = _cameraJumpLerpValue[3];
            }
        }
        float[] _cameraJumpLerpValue;
        float lerp;
        float lerpSpeed = 1.2f;
        float lerpMax = 20;

        public void SetFlyState(int objId, int flyCount, TripleJump_FristRoleFly.EFlyState flyState, float maxHighPointTime0) {
            if (TripleJump_FristRoleFly.CPara.firstRoleId != objId) {
                return;
            }
            this.flyCount = flyCount;
            switch (flyState) {
                case TripleJump_FristRoleFly.EFlyState.e01_startJump:
                    // Debug.LogErrorFormat("当前阶段____________{0}____{1}_____{2}", flyCount, flyState, speedZ);

                    isCanChangeLerp = false;
                    //isCanChangeLerp = true;
                    switch (flyCount) {
                        case 1:
                            _camJumpLerpValue = GlobalTripleJumpCfg.cameraJumpLerpValue01;
                            break;
                        case 2:

                            _camJumpLerpValue = GlobalTripleJumpCfg.cameraJumpLerpValue02;
                            break;
                        case 3:

                            _camJumpLerpValue = GlobalTripleJumpCfg.cameraJumpLerpValue03;
                            break;
                        case 4:

                            _camJumpLerpValue = GlobalTripleJumpCfg.cameraJumpLerpValue04;
                            break;
                    }
                    lerpSpeed = (_cameraJumpLerpValue[3] - _cameraJumpLerpValue[1]) * maxHighPointTime0 / _cameraJumpLerpValue[2];
                    float startWaitTime = _camJumpLerpValue[0] * maxHighPointTime0;
                    //CObj.mono.S_Delay(startWaitTime).SetPauseEnd("").onCallback = delegate() {
                    CDelayMain.Delay(startWaitTime).onCallback = delegate {
                        isCanChangeLerp = true;
                    };
                    break;
                default: break;
            }

            this.maxHighPointTime = maxHighPointTime0;
            // Debug.LogErrorFormat("S_SetFlyState_____{0}_____{1}____{2}____{3}______________________", flyCount, flyState,maxHighPointTime, lerpRatio);
        }
    }
}
